package com.culturalCenter.dataCenter.service.impl.passengerflow;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.culturalCenter.dataCenter.client.SdkClient;
import com.culturalCenter.dataCenter.customEntity.passengerflow.CustomPassengerFlowStatisticsInfo;
import com.culturalCenter.dataCenter.customEntity.requestParam.PassengerFlowRequestParam;
import com.culturalCenter.dataCenter.customEntity.responseParam.passengerflow.*;
import com.culturalCenter.dataCenter.mapper.activity.ActivityServedNumberMapper;
import com.culturalCenter.dataCenter.service.passengerflow.PassengerFlowPopulationService;
import com.culturalCenter.dataCenter.vo.PassengerFlowVo;
import com.dahuatech.hutool.http.Method;
import com.dahuatech.hutool.json.JSONUtil;
import com.dahuatech.icc.exception.ClientException;
import com.dahuatech.icc.oauth.http.DefaultClient;
import com.dahuatech.icc.oauth.http.IClient;
import com.dahuatech.icc.oauth.model.v202010.GeneralRequest;
import com.dahuatech.icc.oauth.model.v202010.GeneralResponse;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * @Author zhao
 * @Date 2020/12/14 9:38
 */
@Service
public class PassengerFlowPopulationServiceImpl implements PassengerFlowPopulationService {


    @Resource
    private ActivityServedNumberMapper activityServedNumberMapper;

    @Value("${passengerFlow.hostname}")
    private String hostname;
    /**
     * 统计区域编号，多个用逗号隔开
     */
    @Value("${passengerFlow.regionCode}")
    private String regionCode;
    /**
     * 人员身份，多个用逗号隔开
     */
    @Value("${passengerFlow.personType}")
    private String personType;
    /**
     * 部门编号(多个用逗号隔开，非必填项)
     */
    @Value("${passengerFlow.department}")
    private String department;
    /**
     * 区域类型，详情见区域类型字典
     */
    @Value("${passengerFlow.regionType}")
    private String regionType;
    /**
     * 公共文化中心子区域编号列表
     */
    @Value("${passengerFlow.culturalCenter}")
    private List<String> culturalCenter;
    /**
     * 翰墨园子区域编号列表
     */
    @Value("${passengerFlow.hanmoGarden}")
    private List<String> hanmoGarden;
    /**
     * 广府园子区域编号列表
     */
    @Value("${passengerFlow.guangfuGarden}")
    private List<String> guangfuGarden;
    /**
     * 广绣园子区域编号列表
     */
    @Value("${passengerFlow.guangxiuGarden}")
    private List<String> guangxiuGarden;
    /**
     * 曲艺园子区域编号列表
     */
    @Value("${passengerFlow.quyiGarden}")
    private List<String> quyiGarden;
    /**
     * 百果园子区域编号列表
     */
//    @Value("${passengerFlow.baiguoGarden}")
//    private List<String> baiguoGarden;

    @Override
    public PassengerFlowIndexResponse getIndexDate(String userId, String userName, String token, String searchKey, PassengerFlowRequestParam param, String timeType) throws Exception {
        PassengerFlowIndexResponse passengerFlowIndexResponse = new PassengerFlowIndexResponse();
        List<PassengerFlowRemainderResponse> responseList = getNowTimePopulation(userId, userName, token, searchKey);
        // 实时客流数
        // 今日到馆
        // 在馆人数
        // 今日在场人数报表
        // 上月同时间在场人数报表

        return passengerFlowIndexResponse;
    }

    @Override
    public List<PassengerFlowPopulationResponse> getRealTimeData(String userId, String userName, String token, PassengerFlowRequestParam param, String timeType) throws Exception {
        List<PassengerFlowPopulationResponse> list = new ArrayList<>();

        String url = hostname + "/CardSolution/statistics/realTimeReport/chart/" + timeType + "?userId=" + userId + "&userName=" + userName + "&token=" + token;
        Map<String, Object> map = new HashMap<>();
        map.put("regionCode", param.getRegionCode());
        map.put("statisticStartTime", param.getStatisticStartTime());
        map.put("statisticEndTime", param.getStatisticEndTime());
        map.put("personType", param.getPersonType());
        map.put("department", param.getDepartment());
        map.put("regionType", param.getRegionType());
        Map<String, String> headMap = new HashMap<>();
        headMap.put("content-Type", "application/json");
        String returnInfo = SdkClient.post(url, JSON.toJSONString(map), headMap);
        JSONObject jsonObject = JSON.parseObject(returnInfo);
        JSONArray dataArrOut = jsonObject.getJSONArray("data");

        for (int i = 0; i < dataArrOut.size(); i++) {
            PassengerFlowPopulationResponse response = new PassengerFlowPopulationResponse();

            String time = dataArrOut.getJSONObject(i).getString("time");
            if (!time.isEmpty()) {
                response.setTime(time);
            }
            List<CustomPassengerFlowStatisticsInfo> listMainBody = new ArrayList<>();
            JSONArray dataArrInner = ((JSONObject) dataArrOut.get(i)).getJSONArray("data");
            for (int j = 0; j < dataArrInner.size(); j++) {
                String showTime = dataArrInner.getJSONObject(j).getString("showTime");
                String keyTime = dataArrInner.getJSONObject(j).getString("keyTime");
                Boolean timeIsRange = dataArrInner.getJSONObject(j).getBoolean("timeIsRange");
                Date useTime = dataArrInner.getJSONObject(j).getDate("useTime");
                String type = dataArrInner.getJSONObject(j).getString("type");
                Long remainder = dataArrInner.getJSONObject(j).getLong("remainder");

                CustomPassengerFlowStatisticsInfo statisticsInfo = new CustomPassengerFlowStatisticsInfo();
                statisticsInfo.setShowTime(showTime);
                statisticsInfo.setKeyTime(keyTime);
                statisticsInfo.setTimeIsRange(timeIsRange);
                statisticsInfo.setUseTime(useTime);
                statisticsInfo.setType(type);
                statisticsInfo.setRemainder(remainder);
                listMainBody.add(statisticsInfo);
            }
            if (CollectionUtils.isNotEmpty(listMainBody)) {
                response.setList(listMainBody);
            }

            list.add(response);
        }

        return list;
    }

    @Override
    public Map<String, List<PassengerFlowPopulationResponse>> getInAndOutData(String userId, String userName, String token, PassengerFlowRequestParam param, String timeType) throws Exception {
        Map<String, List<PassengerFlowPopulationResponse>> listMap = new HashMap<>();

        String url = hostname + "/CardSolution/statistics/inAndOutReport/chart/" + timeType + "?userId=" + userId + "&userName=" + userName + "&token=" + token;
        Map<String, Object> map = new HashMap<>();
        map.put("regionCode", param.getRegionCode());
        map.put("statisticStartTime", param.getStatisticStartTime());
        map.put("statisticEndTime", param.getStatisticEndTime());
        map.put("personType", param.getPersonType());
        map.put("department", param.getDepartment());
        map.put("regionType", param.getRegionType());
        Map<String, String> headMap = new HashMap<>();
        headMap.put("content-Type", "application/json");
        String returnInfo = SdkClient.post(url, JSON.toJSONString(map), headMap);
        JSONObject jsonObject = JSON.parseObject(returnInfo);
        JSONObject jsonObjectData = JSON.parseObject(jsonObject.getString("data"));

        // 进人数
        List<PassengerFlowPopulationResponse> listIn = new ArrayList<>();
        JSONArray inArr = jsonObjectData.getJSONArray("in");
        for (int i = 0; i < inArr.size(); i++) {
            PassengerFlowPopulationResponse response = new PassengerFlowPopulationResponse();

            String time = inArr.getJSONObject(i).getString("time");
            if (!time.isEmpty()) {
                response.setTime(time);
            }
            List<CustomPassengerFlowStatisticsInfo> listMainBody = new ArrayList<>();
            JSONArray dataArrInner = ((JSONObject) inArr.get(i)).getJSONArray("data");
            for (int j = 0; j < dataArrInner.size(); j++) {
                String showTime = dataArrInner.getJSONObject(j).getString("showTime");
                String keyTime = dataArrInner.getJSONObject(j).getString("keyTime");
                Boolean timeIsRange = dataArrInner.getJSONObject(j).getBoolean("timeIsRange");
                Date useTime = dataArrInner.getJSONObject(j).getDate("useTime");
                String type = dataArrInner.getJSONObject(j).getString("type");
                Long remainder = dataArrInner.getJSONObject(j).getLong("remainder");
                CustomPassengerFlowStatisticsInfo statisticsInfo = new CustomPassengerFlowStatisticsInfo();
                statisticsInfo.setShowTime(showTime);
                statisticsInfo.setKeyTime(keyTime);
                statisticsInfo.setTimeIsRange(timeIsRange);
                statisticsInfo.setUseTime(useTime);
                statisticsInfo.setType(type);
                statisticsInfo.setRemainder(remainder);
                listMainBody.add(statisticsInfo);
            }
            if (CollectionUtils.isNotEmpty(listMainBody)) {
                response.setList(listMainBody);
            }
            listIn.add(response);
        }
        listMap.put("in", listIn);

        // 出人数
        List<PassengerFlowPopulationResponse> listOut = new ArrayList<>();
        JSONArray outArr = jsonObjectData.getJSONArray("out");
        for (int i = 0; i < outArr.size(); i++) {
            PassengerFlowPopulationResponse response = new PassengerFlowPopulationResponse();

            String time = outArr.getJSONObject(i).getString("time");
            if (!time.isEmpty()) {
                response.setTime(time);
            }
            List<CustomPassengerFlowStatisticsInfo> listMainBody = new ArrayList<>();
            JSONArray dataArrOut = ((JSONObject) outArr.get(i)).getJSONArray("data");
            for (int j = 0; j < dataArrOut.size(); j++) {
                String showTime = dataArrOut.getJSONObject(j).getString("showTime");
                String keyTime = dataArrOut.getJSONObject(j).getString("keyTime");
                Boolean timeIsRange = dataArrOut.getJSONObject(j).getBoolean("timeIsRange");
                Date useTime = dataArrOut.getJSONObject(j).getDate("useTime");
                String type = dataArrOut.getJSONObject(j).getString("type");
                Long remainder = dataArrOut.getJSONObject(j).getLong("remainder");
                CustomPassengerFlowStatisticsInfo statisticsInfo = new CustomPassengerFlowStatisticsInfo();
                statisticsInfo.setShowTime(showTime);
                statisticsInfo.setKeyTime(keyTime);
                statisticsInfo.setTimeIsRange(timeIsRange);
                statisticsInfo.setUseTime(useTime);
                statisticsInfo.setType(type);
                statisticsInfo.setRemainder(remainder);
                listMainBody.add(statisticsInfo);
            }
            if (CollectionUtils.isNotEmpty(listMainBody)) {
                response.setList(listMainBody);
            }

            listOut.add(response);
        }
        listMap.put("out", listOut);

        return listMap;
    }

    @Override
    public List<PassengerFlowRemainderResponse> getNowTimePopulation(String userId, String userName, String token, String searchKey) throws Exception {
        List<PassengerFlowRemainderResponse> passengerFlowRemainderResponseList = new ArrayList<>();

        String url = hostname + "/CardSolution/statistics/regionConfig/list?userId=" + userId + "&userName=" + userName + "&token=" + token;
        Map<String, Object> map = new HashMap<>();
        map.put("searchKey", searchKey);
        Map<String, String> headMap = new HashMap<>();
        headMap.put("content-Type", "application/json");
        String returnInfo = SdkClient.post(url, JSON.toJSONString(map), headMap);
        JSONObject jsonObject = JSON.parseObject(returnInfo);
        JSONArray dataArr = jsonObject.getJSONArray("data");

        for (int i = 0; i < dataArr.size(); i++) {
            PassengerFlowRemainderResponse passengerFlowRemainderResponse = new PassengerFlowRemainderResponse();

            String regionCode = dataArr.getJSONObject(i).getString("regionCode");
            int regionType = Integer.parseInt(dataArr.getJSONObject(i).getString("regionType"));
            String regionName = dataArr.getJSONObject(i).getString("regionName");
            int remainder = Integer.parseInt(dataArr.getJSONObject(i).getString("remainder"));
            int enterNumber = Integer.parseInt(dataArr.getJSONObject(i).getString("enterNumber"));
            int outNumber = Integer.parseInt(dataArr.getJSONObject(i).getString("outNumber"));

            passengerFlowRemainderResponse.setRegionCode(regionCode);
            passengerFlowRemainderResponse.setRegionType(regionType);
            passengerFlowRemainderResponse.setRegionName(regionName);
            passengerFlowRemainderResponse.setRemainder(remainder);
            passengerFlowRemainderResponse.setEnterNumber(enterNumber);
            passengerFlowRemainderResponse.setOutNumber(outNumber);
            passengerFlowRemainderResponseList.add(passengerFlowRemainderResponse);
        }
        return passengerFlowRemainderResponseList;
    }

    @Override
    public List<PassengerFlowIdentityInfoResponse> getIdentityAndDepartment(String userId, String userName, String token, long id) throws Exception {
        String url = hostname + "/CardSolution/card/person/queryById?userId=" + userId + "&userName=" + userName + "&token=" + token;
        Map<String, Object> map = new HashMap<>();
        map.put("id", id);
        Map<String, String> headMap = new HashMap<>();
        headMap.put("content-Type", "application/json");
        String returnInfo = SdkClient.post(url, JSON.toJSONString(map), headMap);
        JSONObject jsonObject = JSON.parseObject(returnInfo);

        // 处理请求结果信息
        List<PassengerFlowIdentityInfoResponse> passengerFlowIdentityInfoResponseList = new ArrayList<>();
        JSONObject jsonObjectData = jsonObject.getJSONObject("data");
        JSONArray cardsArr = jsonObjectData.getJSONArray("cards");
        for (int i = 0; i < cardsArr.size(); i++) {
            PassengerFlowIdentityInfoResponse passengerFlowIdentityInfoResponse = new PassengerFlowIdentityInfoResponse();
            String deptName = cardsArr.getJSONObject(i).getString("deptName");
            String personIdentityId = String.valueOf(cardsArr.getJSONObject(i).getString("personIdentityId"));
            passengerFlowIdentityInfoResponse.setDeptName(deptName);
            passengerFlowIdentityInfoResponse.setPersonIdentityId(personIdentityId);
            passengerFlowIdentityInfoResponseList.add(passengerFlowIdentityInfoResponse);
        }

        return passengerFlowIdentityInfoResponseList;
    }

    @Override
    public List<PassengerFlowPopulationResponse> getReport(PassengerFlowRequestParam param) throws ClientException {
        List<PassengerFlowPopulationResponse> list = new ArrayList<>();

        IClient iClient = new DefaultClient();
        GeneralRequest generalRequest = new GeneralRequest("/evo-apigw/evo-passengerflow/1.0.0/statistics/realTimeReport/chart/hour", Method.POST);
        Map<String, Object> hashMap = new HashMap<>();
        hashMap.put("statisticStartTime", param.getStatisticStartTime());
        hashMap.put("statisticEndTime", param.getStatisticEndTime());
        hashMap.put("regionCode", regionCode);
        hashMap.put("personType", personType);
        hashMap.put("department", department);
        hashMap.put("regionType", regionType);
        generalRequest.body(JSONUtil.toJsonStr(hashMap));
        GeneralResponse generalResponse = iClient.doAction(generalRequest, generalRequest.getResponseClass());
        JSONObject jsonObject = JSON.parseObject(generalResponse.getResult());
        JSONArray dataArrOut = jsonObject.getJSONArray("data");

        for (int i = 0; i < dataArrOut.size(); i++) {
            PassengerFlowPopulationResponse response = new PassengerFlowPopulationResponse();

            String time = dataArrOut.getJSONObject(i).getString("time");
            if (!time.isEmpty()) {
                response.setTime(time);
            }
            List<CustomPassengerFlowStatisticsInfo> listMainBody = new ArrayList<>();
            JSONArray dataArrInner = ((JSONObject) dataArrOut.get(i)).getJSONArray("data");
            for (int j = 0; j < dataArrInner.size(); j++) {
                String showTime = dataArrInner.getJSONObject(j).getString("showTime");
                String keyTime = dataArrInner.getJSONObject(j).getString("keyTime");
                Boolean timeIsRange = dataArrInner.getJSONObject(j).getBoolean("timeIsRange");
                Date useTime = dataArrInner.getJSONObject(j).getDate("useTime");
                String type = dataArrInner.getJSONObject(j).getString("type");
                Long remainder = dataArrInner.getJSONObject(j).getLong("remainder");

                CustomPassengerFlowStatisticsInfo statisticsInfo = new CustomPassengerFlowStatisticsInfo();
                statisticsInfo.setShowTime(showTime);
                statisticsInfo.setKeyTime(keyTime);
                statisticsInfo.setTimeIsRange(timeIsRange);
                statisticsInfo.setUseTime(useTime);
                statisticsInfo.setType(type);
                statisticsInfo.setRemainder(remainder);
                listMainBody.add(statisticsInfo);
            }
            if (CollectionUtils.isNotEmpty(listMainBody)) {
                response.setList(listMainBody);
            }

            list.add(response);
        }

        return list;
    }

    @Override
    public List<PassengerFlowRemainderResponse> getAllRegions(String searchKey) throws ClientException {
        List<PassengerFlowRemainderResponse> passengerFlowRemainderResponseList = new ArrayList<>();

        IClient iClient = new DefaultClient();
        GeneralRequest generalRequest = new GeneralRequest("/evo-apigw/evo-passengerflow/1.0.0/statistics/regionConfig/page", Method.POST);
        Map<String, Object> hashMap = new HashMap<>();
        hashMap.put("pageNum", 1);
        hashMap.put("pageSize", 10000);
        hashMap.put("singleCondition", StrUtil.isBlank(searchKey) ? "" : searchKey);
        generalRequest.body(JSONUtil.toJsonStr(hashMap));
        GeneralResponse generalResponse = iClient.doAction(generalRequest, generalRequest.getResponseClass());
        JSONObject jsonObject = JSON.parseObject(generalResponse.getResult());
        JSONArray dataArrOut = jsonObject.getJSONObject("data").getJSONArray("pageData");

        for (int i = 0; i < dataArrOut.size(); i++) {
            PassengerFlowRemainderResponse passengerFlowRemainderResponse = new PassengerFlowRemainderResponse();

            String regionCode = dataArrOut.getJSONObject(i).getString("regionCode");
            int regionType = Integer.parseInt(dataArrOut.getJSONObject(i).getString("regionType"));
            String regionName = dataArrOut.getJSONObject(i).getString("regionName");
            int remainder = Integer.parseInt(dataArrOut.getJSONObject(i).getString("remainder"));
            int enterNumber = Integer.parseInt(dataArrOut.getJSONObject(i).getString("enterNumber"));
            int outNumber = Integer.parseInt(dataArrOut.getJSONObject(i).getString("outNumber"));

            passengerFlowRemainderResponse.setRegionCode(regionCode);
            passengerFlowRemainderResponse.setRegionType(regionType);
            passengerFlowRemainderResponse.setRegionName(regionName);
            passengerFlowRemainderResponse.setRemainder(remainder);
            passengerFlowRemainderResponse.setEnterNumber(enterNumber);
            passengerFlowRemainderResponse.setOutNumber(outNumber);
            passengerFlowRemainderResponseList.add(passengerFlowRemainderResponse);
        }
        return passengerFlowRemainderResponseList;
    }

    @Override
    public List<PassengerFlowRemainderResponse> getTotalPopulation() throws ClientException {
        List<PassengerFlowRemainderResponse> passengerFlowRemainderResponseList = new ArrayList<>();

        IClient iClient = new DefaultClient();
        GeneralRequest generalRequest = new GeneralRequest("/evo-apigw/evo-passengerflow/1.0.0/statistics/regionConfig/page", Method.POST);
        Map<String, Object> hashMap = new HashMap<>();
        hashMap.put("pageNum", 1);
        hashMap.put("pageSize", 10000);
        hashMap.put("singleCondition", "");
        generalRequest.body(JSONUtil.toJsonStr(hashMap));
        GeneralResponse generalResponse = iClient.doAction(generalRequest, generalRequest.getResponseClass());
        JSONObject jsonObject = JSON.parseObject(generalResponse.getResult());
        JSONArray dataArrOut = jsonObject.getJSONObject("data").getJSONArray("pageData");

        PassengerFlowRemainderResponse result = new PassengerFlowRemainderResponse();
        int remainder = result.getRemainder();
        int enterNumber = result.getEnterNumber();
        int outNumber = result.getOutNumber();
        for (int i = 0; i < dataArrOut.size(); i++) {
            int remainder0 = Integer.parseInt(dataArrOut.getJSONObject(i).getString("remainder"));
            int enterNumber0 = Integer.parseInt(dataArrOut.getJSONObject(i).getString("enterNumber"));
            int outNumber0 = Integer.parseInt(dataArrOut.getJSONObject(i).getString("outNumber"));
            remainder += remainder0;
            enterNumber += enterNumber0;
            outNumber += outNumber0;
        }
        result.setRemainder(remainder);
        result.setEnterNumber(enterNumber);
        result.setOutNumber(outNumber);
        result.setRegionName("");
        result.setRegionCode("");
        passengerFlowRemainderResponseList.add(result);

        return passengerFlowRemainderResponseList;
    }

    @Override
    public List<PassengerFlowAreaInfoResponse> getAreaInfo() throws ClientException {
        List<PassengerFlowAreaInfoResponse> responseList = new ArrayList<>();

        List<String> parentNames = new ArrayList<>(Arrays.asList("公共文化中心", "翰墨园", "广府园", "广绣园", "曲艺园", "百果园"));
        parentNames.forEach(name -> {
            PassengerFlowAreaInfoResponse infoResponse = new PassengerFlowAreaInfoResponse();
            infoResponse.setRegionCode(("0" + parentNames.indexOf(name)));
            infoResponse.setRegionName(name);
            infoResponse.setParentCode("0");
            responseList.add(infoResponse);
        });

        List<PassengerFlowRemainderResponse> allRegions = getAllRegions(null);
        allRegions.forEach(region -> {
            PassengerFlowAreaInfoResponse infoResponse = new PassengerFlowAreaInfoResponse();
            String regionName = region.getRegionName();
            infoResponse.setRegionCode(region.getRegionCode());
            infoResponse.setRegionName(regionName);
            infoResponse.setRemainder(region.getRemainder());
            infoResponse.setOverrun(region.getGalleryful() < region.getRemainder() ? 1 : 0);
            infoResponse.setParentCode(culturalCenter.contains(regionName) ? responseList.stream().filter(response -> "公共文化中心".equals(response.getRegionName())).findAny().get().getRegionCode() :
                    hanmoGarden.contains(regionName) ? responseList.stream().filter(response -> "翰墨园".equals(response.getRegionName())).findAny().get().getRegionCode() :
                            guangfuGarden.contains(regionName) ? responseList.stream().filter(response -> "广府园".equals(response.getRegionName())).findAny().get().getRegionCode() :
                                    guangxiuGarden.contains(regionName) ? responseList.stream().filter(response -> "广绣园".equals(response.getRegionName())).findAny().get().getRegionCode() :
                                            quyiGarden.contains(regionName) ? responseList.stream().filter(response -> "曲艺园".equals(response.getRegionName())).findAny().get().getRegionCode() :
                                                    responseList.stream().filter(response -> "百果园".equals(response.getRegionName())).findAny().get().getRegionCode());
            responseList.add(infoResponse);
            PassengerFlowAreaInfoResponse parent = responseList.stream().filter(response -> response.getRegionCode().equals(infoResponse.getRegionCode())).findAny().get();
            if (parent.getOverrun() != 1) {
                parent.setOverrun(infoResponse.getOverrun());
            }
            parent.setRemainder(parent.getRemainder() + infoResponse.getRemainder());
        });

        return responseList;
    }

    @Override
    public List<PassengerFlowVo> getCurrentMonthReport(String type) {

        return  activityServedNumberMapper.getCurrentMonthReport(type);
    }

}
